package com.javatest.redpacket.config;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import redis.clients.jedis.JedisPoolConfig;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author liuziyang
 * @create 2020-08-03 22:07
 */
@Configuration
@ComponentScan(value = "com.javatest.redpacket.*", useDefaultFilters = false,
        includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Service.class, Repository.class})})
@PropertySource("classpath:db.properties")
// 实现接口TransactionManagementConfigurer,这样可以配置注解驱动事务
@EnableTransactionManagement
public class RootConfig implements TransactionManagementConfigurer {
    private DataSource dataSource;

    /**
     * 初始化数据库配置
     * Init data source data source.
     *
     * @return the data source
     */
    @Bean("dataSource")
    public DataSource initDataSource() {
        if (dataSource != null) {
            return dataSource;
        }
        Properties properties = new Properties();
        properties.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
        properties.setProperty("db.url", "jdbc:mysql://10.2.32.186:3306/spring_test?useSSL=false&serverTimezone=UTC");
        properties.setProperty("db.username", "root");
        properties.setProperty("db.password", "crscd123@");
        properties.setProperty("maxActive", "200");
        properties.setProperty("maxWait", "30000");

        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return this.dataSource;
    }

    /**
     * Init sql session factory sql session factory bean.
     *
     * @return the sql session factory bean
     */
    @Bean("sqlSessionFactoryBean")
    public SqlSessionFactoryBean initSqlSessionFactory() {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(initDataSource());
        // 配置mybatis配置文件
        final Resource resource = new ClassPathResource("sqlMapConfig.xml");
        sessionFactoryBean.setConfigLocation(resource);
        return sessionFactoryBean;
    }

    /**
     * 通过自动扫描,发现Mabitis Mapper接口
     * Init mapper scanner mapper scanner configurer.
     *
     * @return the mapper scanner configurer
     */
    @Bean
    public MapperScannerConfigurer initMapperScanner() {
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.javatest.redpacket.dao");
        configurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        configurer.setAnnotationClass(Repository.class);
        return configurer;
    }

    /**
     * 实现接口方法，注册注解事务
     *
     * @return
     */
    @Override
    @Bean("annotationDrivenTransactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(initDataSource());
    }

    /**
     * Init redis template redis template.
     *
     * @return the redis template
     */
    @Bean("redisTemplate")
    public RedisTemplate initRedisTemplate() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        //最大空闲数
        poolConfig.setMaxIdle(50);
        //最大连接数
        poolConfig.setMaxTotal(100);
        //最大等待毫秒数
        poolConfig.setMaxWaitMillis(20000);
        //创建jedis连接工厂
        JedisConnectionFactory connectionFactory = new JedisConnectionFactory(poolConfig);
        connectionFactory.setHostName("localhost");
        connectionFactory.setPort(6379);
        //调用初始化方法,没有会抛出异常
        connectionFactory.afterPropertiesSet();
        //自定义Redis序列化器
        RedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
        RedisSerializer stringSerializer = new StringRedisSerializer();
        //定义RedisTemplate,并配置连接工厂
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(connectionFactory);
        //设置序列化器
        redisTemplate.setDefaultSerializer(stringSerializer);
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);
        return redisTemplate;
    }

}
